package server

import (
	"errors"
	"fmt"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"net"
	"strconv"
	"sync"
)

var lock sync.Mutex

type GrpcServer struct {
	Port                  int
	waitRegisterList      []ServiceDesc
	Server                *grpc.Server
	onServerStartCallBack func()
	TlsPublicPath         string
	TlsPrivatePath        string
}
type ServiceDesc struct {
	Name        string
	Description string
	registerFun func(rpcServer *grpc.Server)
}

func (server *GrpcServer) RegisterService(desc ServiceDesc, registerFun func(rpcServer *grpc.Server)) {
	lock.Lock()
	if server.waitRegisterList == nil {
		server.waitRegisterList = make([]ServiceDesc, 0)
	}
	desc.registerFun = registerFun
	server.waitRegisterList = append(server.waitRegisterList, desc)
	lock.Unlock()
}
func (server *GrpcServer) OnServerStart(callBack func()) {
	server.onServerStartCallBack = callBack
}

func (server *GrpcServer) Start() error {
	listen, err := net.Listen("tcp", ":"+strconv.Itoa(server.Port))
	if err != nil {
		return errors.New("failed listen port " + strconv.Itoa(server.Port))
	}
	var s *grpc.Server
	if server.TlsPrivatePath != "" && server.TlsPublicPath != "" {
		creds, err := credentials.NewServerTLSFromFile(server.TlsPublicPath,
			server.TlsPrivatePath)
		if err != nil {
			return err
		}
		s = grpc.NewServer(grpc.Creds(creds))
	} else {
		s = grpc.NewServer()
	}
	for _, serviceDesc := range server.waitRegisterList {
		serviceDesc.registerFun(s)
		fmt.Println(serviceDesc.Name, "服务注册成功")
	}
	go server.onServerStartCallBack()
	s.Serve(listen)
	return nil
}
